﻿#include <memory>
#include "acis/af_api.hxx"
#include "acis/facet_options.hxx"
#include "discrete_face.hxx"
#include "discrete_edge.hxx"


outcome api_discrete_bodies(ENTITY_LIST const& bodies, facet_options* fo, AcisOptions* ao) {
    outcome out;
    for (ENTITY* ent = bodies.first(); ent != nullptr; ent = bodies.next()) {
        /* 离散边 */
        // 创建一个面可视化构造的选项
        // 可有edge_quality和face_quality两个选项
        facet_options_visualization* fo = ACIS_NEW facet_options_visualization();

        // 设置边和面的quality选项
        fo->set_edge_quality(edge_quality_level::better);
        fo->set_face_quality(face_quality_level::medium_coarse);
        FacetContext facet_context(ent, fo);
        std::unique_ptr<FacetContext> facet_context_ptr = std::make_unique<FacetContext>(facet_context);

        FacetParameters facet_parameters = facet_context_ptr->GetParameters();
        // 获取到边的列表
        ENTITY_LIST el;
        api_get_edges(ent, el);
        // 针对每条边进行离散
        for (EDGE* e = dynamic_cast<EDGE*>(el.first()); e != nullptr; e = dynamic_cast<EDGE*>(el.next())) {
            // 调用函数离散边
            AF_POINT* out_points = nullptr;
            int out_cnt = 0;
            out = facet_edge(e, facet_parameters.distance_tolerance_edge, facet_parameters.angle_tolerance_edge, out_points, out_cnt);
            if (!out.ok()) {
                printf("ERROR: facet_edge returns a wrong outcome.\n");
            }

            // EDGEFaceter::facet(e, &facet_parameters);
            // facet_context_ptr->AddEdgeData(e, EdgeMeshData(e));
        }
        /* 离散边end */

        /** 离散面 */
        ENTITY_LIST fl;
        api_get_faces(ent, fl);
        for (FACE* f = (FACE*)fl.first(); f != nullptr; f = (FACE*)fl.next()) {
            // 获取边容差
            // 调用函数离散面
            out = FacetFace(f, facet_context_ptr, facet_parameters.surface_tolerance, facet_parameters.normal_tolerance);
            if (!out.ok()) {
                printf("ERROR: facet_face returns a wrong outcome.\n");
            }
        }
        ACIS_DELETE fo;
        /** 离散面end */
    }

    return outcome();
}

outcome api_discrete_edge(EDGE* in_EDGE,               // EDGE to approximate with linear polygons
    const double in_max_tol,     // max tolerance between real curve and facet
    const double in_max_length,  // max length of facet
    const double in_max_angle,   // max tangental angle facet passes thru
    int& out_count,              // number of points generated
    AF_POINT*& out_points,       // linked list of facets
    AcisOptions* ao = nullptr)             // version==12 for old behavior
{
    /**
     * @todo: 现在的算法没有考虑in_max_length参数，也没有给出应该输出的AF_POINT列表，只是完成了离散功能。
     */
    return facet_edge(in_EDGE, in_max_tol, in_max_angle, out_points, out_count);
}

outcome api_discrete_entities(ENTITY* owner,             // owner of entities in list
    ENTITY_LIST* entity_list,  // list of entities
    facet_options* fo, AcisOptions* ao) {
    return outcome();
}

outcome api_discrete_entity(ENTITY* ent, facet_options* fo, AcisOptions* ao) {
    if (!ent) return outcome();

    API_BEGIN

        if (is_BODY(ent) || is_FACE(ent)) {
            ENTITY_LIST bl;
            bl.add(ent);
            api_discrete_bodies(bl, fo, ao);
        }
        else if (is_EDGE(ent)) {
            EDGE* e = (EDGE*)ent;
            double tol = 0, length = 0, angle = 0;
            int count = 0;
            AF_POINT* pts = nullptr;
            SPAposition pa, pb;
            api_get_entity_box(ent, pa, pb);

            double diag = (pb - pa).len();
            /**
             * @todo: 现在的算法默认使用facet_options_visualization选项，因此不使用输入的fo指针，而是在下面指定选项参数.
             */
            facet_options_visualization* f = ACIS_NEW facet_options_visualization();
            f->set_edge_quality(edge_quality_level::better);
            f->set_face_quality(face_quality_level::medium_coarse);
            get_edge_tolerance(diag, f, tol, angle);
            api_discrete_edge(e, tol, length, angle, count, pts);
        }
    API_END
        return outcome();
}